package main

import (
	"fmt"
	"github.com/TeaOSLab/EdgeAdmin/internal/apps"
	"github.com/TeaOSLab/EdgeAdmin/internal/configs"
	teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
	"github.com/TeaOSLab/EdgeAdmin/internal/gen"
	"github.com/TeaOSLab/EdgeAdmin/internal/nodes"
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web"
	_ "github.com/iwind/TeaGo/bootstrap"
	"github.com/iwind/TeaGo/maps"
	"github.com/iwind/gosock/pkg/gosock"
)

func main() {
	app := apps.NewAppCmd().
		Version(teaconst.Version).
		Product(teaconst.ProductName).
		Usage(teaconst.ProcessName+" [-v|start|stop|restart|service|daemon|reset|recover|demo]").
		Usage(teaconst.ProcessName+" [dev|prod]").
		Option("-h", "show this help").
		Option("-v", "show version").
		Option("start", "start the service").
		Option("stop", "stop the service").
		Option("restart", "restart the service").
		Option("service", "register service into systemd").
		Option("daemon", "start the service with daemon").
		Option("reset", "reset configs").
		Option("recover", "enter recovery mode").
		Option("demo", "switch to demo mode").
		Option("dev", "switch to 'dev' mode").
		Option("prod", "switch to 'prod' mode")

	app.On("daemon", func() {
		nodes.NewAdminNode().Daemon()
	})
	app.On("service", func() {
		err := nodes.NewAdminNode().InstallSystemService()
		if err != nil {
			fmt.Println("[ERROR]install failed: " + err.Error())
			return
		}
		fmt.Println("done")
	})
	app.On("reset", func() {
		err := configs.ResetAPIConfig()
		if err != nil {
			fmt.Println("[ERROR]reset failed: " + err.Error())
			return
		}
		fmt.Println("done")
	})
	app.On("recover", func() {
		sock := gosock.NewTmpSock(teaconst.ProcessName)
		if !sock.IsListening() {
			fmt.Println("[ERROR]the service not started yet, you should start the service first")
			return
		}
		_, err := sock.Send(&gosock.Command{Code: "recover"})
		if err != nil {
			fmt.Println("[ERROR]enter recovery mode failed: " + err.Error())
			return
		}
		fmt.Println("enter recovery mode successfully")
	})
	app.On("demo", func() {
		sock := gosock.NewTmpSock(teaconst.ProcessName)
		if !sock.IsListening() {
			fmt.Println("[ERROR]the service not started yet, you should start the service first")
			return
		}
		reply, err := sock.Send(&gosock.Command{Code: "demo"})
		if err != nil {
			fmt.Println("[ERROR]change demo mode failed: " + err.Error())
			return
		}
		var isDemo = maps.NewMap(reply.Params).GetBool("isDemo")
		if isDemo {
			fmt.Println("change demo mode to: on")
		} else {
			fmt.Println("change demo mode to: off")
		}
	})
	app.On("generate", func() {
		err := gen.Generate()
		if err != nil {
			fmt.Println("generate failed: " + err.Error())
			return
		}
	})
	app.On("dev", func() {
		var env = "dev"
		var sock = gosock.NewTmpSock(teaconst.ProcessName)
		_, err := sock.Send(&gosock.Command{
			Code:   env,
			Params: nil,
		})
		if err != nil {
			fmt.Println("failed to switch to '" + env + "': " + err.Error())
		} else {
			fmt.Println("switch to '" + env + "' ok")
		}
	})
	app.On("prod", func() {
		var env = "prod"
		var sock = gosock.NewTmpSock(teaconst.ProcessName)
		_, err := sock.Send(&gosock.Command{
			Code:   env,
			Params: nil,
		})
		if err != nil {
			fmt.Println("failed to switch to '" + env + "': " + err.Error())
		} else {
			fmt.Println("switch to '" + env + "' ok")
		}
	})
	app.Run(func() {
		adminNode := nodes.NewAdminNode()
		adminNode.Run()
	})
}
